<f-flow fDraggable [vCellSize]="20" [hCellSize]="20"
  (fLoaded)="onLoaded()"
  (fCreateConnection)="addConnection($event)"
  (fReassignConnection)="reassignConnection($event)"
  (fSelectionChange)="selectionChanged($event)"
  (contextmenu)="onContextMenu($event)"
  [cdkContextMenuTriggerFor]="menu.template"
  (cdkContextMenuClosed)="menu.dispose()">
  <f-background>
    <f-circle-pattern />
  </f-background>
  <f-line-alignment></f-line-alignment>
  <f-selection-area></f-selection-area>

  <f-canvas fZoom [fZoomStep]="0.02" [fZoomDblClickStep]="0.1" [scale]="scale()" [position]="position()"
    (fCanvasChange)="onCanvasChange($event)">
    <f-connection-for-create></f-connection-for-create>
    <f-snap-connection fType="bezier" [fSnapThreshold]="100"></f-snap-connection>
    @for (connection of connections(); track connection.key) {
      <f-connection #connComp [fType]="EFConnectionType.BEZIER" [fOffset]="6" [fRadius]="6"
        [fReassignDisabled]="false"
        [fOutputId]="connection.from + '/' + connection.type"
        [fInputId]="connection.to + (connection.type === 'edge' ? '/edge' : '')"
        class="gradient-color cursor-pointer"
        [class.f-selected]="connection.from.startsWith(selectedNodeKey()) || connection.to.startsWith(selectedNodeKey())"
        [class.f-hover]="connection.from.startsWith(hoverNode()) || connection.to.startsWith(hoverNode())"
        [ngClass]="connection.type"
        fStartColor="var(--connection-gradient-1)" fEndColor="var(--connection-gradient-2)"
        [cdkContextMenuTriggerFor]="connContextMenu"
        [cdkContextMenuTriggerData]="{connection: connComp}"
      >
        @if (connection.type === 'edge') {
          <svg viewBox="0 0 6 7" fMarker [type]="eMarkerType.END" class="connection-marker"
              [height]="7" [width]="6"
              [refX]="5.5" [refY]="3.5" markerUnits="strokeWidth" orient="auto">
            <path d="M0.000391006 0L6 3.5L0.000391006 7L0.000391006 0Z"/>
          </svg>
          <svg viewBox="0 0 6 7" fMarker [type]="eMarkerType.SELECTED_END" class="connection-marker"
            [height]="7" [width]="6"
            [refX]="5.5" [refY]="3.5" markerUnits="strokeWidth" orient="auto">
            <path d="M0.000391006 0L6 3.5L0.000391006 7L0.000391006 0Z"/>
          </svg>
        }
      </f-connection>
    }

    @for (node of nodes(); track node.key + node.hash) {
      <div class="w-[240px] group relative pb-1 shadow-sm border border-transparent rounded-[15px] bg-workflow-block-bg hover:shadow-lg hover:z-10"
        [class.ngm-selected]="selectedNodeKey() === node.key"
        [class.f-hover]="hoverNode() === node.key"
        [class.ngm-executor-agent]="node.parentId"
        [ngClass]="selectAgentStatus(node.key) || ''"
        fNode [fNodeId]="node.key"
        [fNodeParentId]="node.parentId"
        fDragHandle
        [fNodePosition]="node.position"
        [fNodeSize]="node.size"
        (fNodePositionChange)="moveNode({key: node.key, point: $event})"
        (fNodeSizeChange)="onSizeChange($event, node)"
        (mousedown)="onMouseDown($event)"
        (mouseenter)="hoverNode.set(node.key)"
        (mouseleave)="hoverNode.set(null)"
        (click)="onSelectNode($event, node)"

        [floatUi]="executionPopper"
        [disabled]="!executions()[node.key]"
        [showTrigger]="eNgxFloatUiTriggers.hover"
        [hideOnClickOutside]="false"
        [hideOnMouseLeave]="false"
        [hideOnScroll]="true"
        [hideTimeout]="300"
        [placement]="eNgxFloatUiPlacements.TOPSTART"
      >
        @switch (node.type) {
          @case('agent') {
            <xpert-studio-node-agent [node]="node" [isRoot]="rootAgent().key === node.key || node.parentId && !!node.entity.xpertId" class=""/>
          }
          @case('knowledge') {
            <xpert-studio-node-knowledge [node]="node" class="" />
          }
          @case('toolset') {
            <xpert-studio-node-toolset [node]="node" class="" />
          }
          @case('workflow') {
            <xpert-studio-node-workflow [node]="node" class="" />
          }
        }

        @if (!node.parentId) {
          <div class="node-toolbar absolute right-0 -top-8 flex items-center gap-1 p-0.5 rounded-lg border-[0.5px] shadow-xs
            bg-white border-gray-100  text-gray-500">
            @if (rootAgent().key !== node.key) {
              <button type="button" class="flex items-center justify-center w-6 h-6 p-0.5 rounded-md cursor-pointer
                hover:bg-red-500/10 hover:text-red-500"
                (click)="removeNode(node.key)">
                <i class="ri-close-line"></i>
              </button>
            }
          </div>
        }

        @if (selectAgentStatus(node.key) === eXpertAgentExecutionEnum.RUNNING) {
          <ngm-spin class="absolute right-2 top-2" />
        }

        <float-ui-content #executionPopper (click)="$event.stopPropagation()" (wheel)="$event.stopPropagation()">
          @if (executions()[node.key]) {
            @for (execution of executions()[node.key]; track execution.id) {
              <xpert-agent-execution-status class="p-2 w-96" [execution]="execution" />
              <xpert-agent-execution-log class="p-2 w-96 max-h-[400px] overflow-y-auto overflow-x-hidden"
                [execution]="execution"
              />
            }
          }
        </float-ui-content>
      </div>
    }

    @for (group of xperts(); track group.key + group.hash) {
      <div class="group" fGroup [fGroupId]="group.key" [fGroupParentId]="group.parentId" [fGroupPosition]="group.position"
        [fGroupSize]="group.size" fDragHandle
        (fGroupPositionChange)="moveXpertGroup($event, group.key)"
        (fGroupSizeChange)="resizeXpertGroup($event, group.key)"
        (mousedown)="onMouseDown($event)"
        (click)="onSelectNode($event, group)"
      >
        <div class="group-title flex items-center gap-1">
          <emoji-avatar [avatar]="group.entity.avatar" small class="shrink-0 mr-2 rounded-lg overflow-hidden shadow-sm" />
          @if (isDisableOutput(group)) {
            <i class="ri-volume-mute-fill mr-1 text-lg text-sky-500"
              [matTooltip]="'PAC.Xpert.DisableOutputTip' | translate: {Default: 'Disable returning the agent\'s output to the user'}"
              matTooltipPosition="above">
            </i>
          }
          <span class="truncate text-text-secondary">{{ group.entity.title || group.entity.name }}</span>
        </div>
        <div fResizeHandle [fResizeHandleType]="eResizeHandleType.LEFT_TOP"></div>
        <div fResizeHandle [fResizeHandleType]="eResizeHandleType.RIGHT_TOP"></div>
        <div fResizeHandle [fResizeHandleType]="eResizeHandleType.LEFT_BOTTOM"></div>
        <div fResizeHandle [fResizeHandleType]="eResizeHandleType.RIGHT_BOTTOM"></div>

        <div fNodeInput [fInputId]="group.key" fInputConnectableSide="top" class="top"></div>

        <div class="node-toolbar absolute right-1 top-1 flex items-center gap-1 p-0.5 rounded-lg border-[0.5px]
          bg-white border-gray-100 shadow-xs text-gray-500">
          <div class="flex items-center justify-center w-6 h-6 p-0.5 rounded-md cursor-pointer
            hover:bg-black/5"
            (click)="expandXpertTeam(group)">
            @if (group.expanded) {
              <i class="ri-collapse-vertical-line"></i>
            } @else {
              <i class="ri-expand-vertical-line"></i>
            }
          </div>
          
          <div class="flex items-center justify-center w-6 h-6 p-0.5 rounded-md cursor-pointer
            hover:bg-red-500/10 hover:text-red-500"
            (click)="removeNode(group.key)">
            <i class="ri-close-line"></i>
          </div>
        </div>
      </div>
    }
  </f-canvas>

  <f-selection-area></f-selection-area>
  <f-minimap></f-minimap>
</f-flow>

<xpert-studio-toolbar class="flex items-center mt-1 gap-2 absolute left-4 bottom-4 z-[9]" />

<xpert-studio-header class="absolute top-0 left-0 z-20 flex items-center justify-between w-full"
  [(sidePanel)]="sidePanel" />

<xpert-studio-panel class="absolute top-14 right-0 bottom-2 flex z-10 outline-none"
  [(sidePanel)]="sidePanel" />

<xpert-studio-context-menu #menu="menuComponent" />

<ng-template #connContextMenu let-connection="connection">
  <div cdkMenu class="cdk-menu__large">
    <div cdkMenuItem class="ngm-cdk-menu-item danger" (click)="removeConnection(connection)">
      <span>{{ 'PAC.Xpert.Remove' | translate: {Default: 'Remove'} }}</span>
    </div>
  </div>
</ng-template>